package com.objective.teste.jogo;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;

import com.objective.teste.model.Animal;
import com.objective.teste.model.Pergunta;

/***
 * Classe UI que define a interface principal com o usuário do Jogo e define as principais interações
 * para a criação da árvore de decisão do jogo
 * 
 * @author rodrigo.postai
 * 
 */
public class Jogo extends JFrame {
	private static final long serialVersionUID = 1787558480518030084L;

	private static final String TITULO = "Animais";
	private static final String TEXTO_INICIAL = "Pense em um animal!";
	private static final String TEXT_BOTAO_INICIAR = "OK";

	private static final String PERGUNTA_FINAL = "O animal que você pensou é %s ?";
	private static final String PERGUNTA_QUAL_ANIMAL = "Qual animal que você pensou?";
	private static final String PERGUNTA_ACAO_COMPARACAO = "Um(a) %s __________ nas um(a) %s não";
	private static final String FINALIZACAO = "Acertei de novo!";

	private final JLabel texto = new JLabel(TEXTO_INICIAL);
	private final JButton botaoIniciar = new JButton(TEXT_BOTAO_INICIAR);

	private final ConfiguracaoInicial jogo;

	public Jogo() {
		super(TITULO);
		jogo = new ConfiguracaoInicial();
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		constroiUI();
	}

	private void constroiUI() {
		Container container = getContentPane();
		container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));

		texto.setAlignmentX(Component.CENTER_ALIGNMENT);
		getContentPane().add(texto);

		botaoIniciar.setAlignmentX(Component.CENTER_ALIGNMENT);
		getContentPane().add(botaoIniciar);

		botaoIniciar.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				iniciarJogo();
			}
		});

		setLocationRelativeTo(null);
	}

	/***
	 * Método responsável por iniciar e definir o fluxo principal da criação da árvore de decisão
	 * e as interações necessárias com o usuário
	 */
	private void iniciarJogo() {

		Animal animalPerguntaAnterior = null;

		Pergunta pergunta = jogo.getPerguntaInicial();

		while (pergunta != null) {

			boolean resposta = exibePerguntaComportamentoAnimal(pergunta);

			Animal animal = resposta ? pergunta.getAnimalAfirmativo()
					: pergunta.getAnimalNegativo();

			if (animal != null) {
				if (animal.getPergunta() == null) {
					resposta = confirmaAnimal(animal);
					if (resposta) {
						mostraMensagemAcerto();
						pergunta = null;
					} else {
						adicionaAnimalArvoreDecisao(pergunta, animal, true);
						pergunta = null;
					}
				} else {
					pergunta = animal.getPergunta();
				}
			} else {
				resposta = confirmaAnimal(animalPerguntaAnterior);
				if (resposta) {
					mostraMensagemAcerto();
					pergunta = null;
				} else {
					adicionaAnimalArvoreDecisao(pergunta,
							animalPerguntaAnterior, false);
					pergunta = null;
				}
			}

			animalPerguntaAnterior = animal;

		}

	}

	/***
	 * Exibe a pergunta sobre o comportamento do animal
	 * @param pergunta
	 * @return
	 */
	private boolean exibePerguntaComportamentoAnimal(Pergunta pergunta) {
		return JOptionPane.showConfirmDialog(this,
				pergunta.getPergunta(), "", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;

	}

	/***
	 * Método responsavel por interagir com o usuário para confirmar o animal
	 * pensado
	 * 
	 * @param animal
	 * @return
	 */
	private boolean confirmaAnimal(Animal animal) {
		String str = String.format(PERGUNTA_FINAL, animal.getNome());
		return JOptionPane.showConfirmDialog(this, str, "",
				JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
	}

	/***
	 * Exibe a mensagem final de acerto da questão
	 */
	private void mostraMensagemAcerto() {
		JOptionPane.showMessageDialog(this, FINALIZACAO);
	}

	/***
	 * Responsável por adicionar um novo nó na árvore de decisão conforme a
	 * resposta da questão anterior do usuário
	 * 
	 * @param pergunta
	 * @param animal
	 * @param respostaPositiva
	 */
	private void adicionaAnimalArvoreDecisao(Pergunta pergunta, Animal animal,
			boolean respostaPositiva) {
		String nome = JOptionPane.showInputDialog(this, PERGUNTA_QUAL_ANIMAL);
		String acao = JOptionPane
				.showInputDialog(
						this,
						String.format(PERGUNTA_ACAO_COMPARACAO, nome,
								animal.getNome()));

		Animal novoAnimal = new Animal(nome);
		Pergunta novaPergunta = new Pergunta(acao);

		if (respostaPositiva) {
			novaPergunta.setAnimalAfirmativo(novoAnimal);
			animal.setPergunta(novaPergunta);
		} else {
			pergunta.setAnimalNegativo(novoAnimal);
			novoAnimal.setPergunta(novaPergunta);
		}
	}

	public static void main(String[] args) {
		Jogo view = new Jogo();
		view.setSize(200, 100);
		view.setVisible(true);
	}

}
